using System;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Text;
using System.Text.RegularExpressions;

namespace Jec.CustomControls
{
    [ToolboxBitmap(typeof(DropDownList)),
    DefaultProperty("Text"),
    ToolboxData("<{0}:ColorPick runat='server' />")]
    public class ColorPick : Control, INamingContainer
    {
        // we need a textbox, a span and a table of which we can set or get properties
        TextBox _TextBox = new TextBox();
        Label _Label = new Label();
        Table MainTable = new Table();

        [Category("Data"),
        Description("Set to true if you want to create the colortables serverside and send them to the browser."),
        DefaultValue(false)]
        public bool ShowColors
        {
            get
            {
                if (ViewState["ShowColors"] == null)
                {
                    return false;//default value
                }
                else
                {
                    return (bool)ViewState["ShowColors"];
                }
            }
            set
            {
                if (value)
                {
                    _Label.Style["visibility"] = "visible";
                }
                else
                {
                    _Label.Style["visibility"] = "hidden";
                }

                MainTable.Visible = value;
                ViewState["ShowColors"] = value;
            }
        }

        [Category("Data"),
        Description("Textbox text."),
        DefaultValue("")]
        public string Text
        {
            get
            {
                return _TextBox.Text;
            }
            set
            {
                Color c;
                if (value.Trim() != "")
                {
                    c = Color.FromName(value);

                    if (!c.IsKnownColor)
                    {
                        string hexvalue = Regex.Replace(value, "[^0-9a-fA-F]", "");

                        if (hexvalue.Length == 6)
                        {
                            c = ColorTranslator.FromHtml("#" + hexvalue);
                            value = ColorTranslator.ToHtml(c);
                        }
                        else
                        {
                            c = Color.White;
                            value = "#Error";
                        }
                    }
                    else
                    {
                        value = ColorTranslator.ToHtml(c);
                    }
                }
                else
                {
                    c = Color.White;
                }

                if (c.GetBrightness() < 0.5)
                {
                    _TextBox.Style["color"] = "white";
                }
                else
                {
                    _TextBox.Style["color"] = "black";
                }

                _TextBox.Text = value;
                _TextBox.Style["background-color"] = ColorTranslator.ToHtml(c);
            }
        }

        protected override void OnInit(EventArgs e)
        {
            // set default visibility of the color tables
            ShowColors = ShowColors;

            //the textbox is added here in order to maintain viewstate
            _TextBox.TextChanged += new EventHandler(TextBox_TextChanged);
            _TextBox.AutoPostBack = true;
            _TextBox.ID = "ColorField";
            Controls.Add(_TextBox);
            base.OnInit(e);
        }

        protected override void CreateChildControls()
        {
            //First we edit the main span
            _Label.Style["position"] = "absolute";
            _Label.ID = "ColorSpan";

            //We need a table for layout and header
            MainTable.Attributes.Add("style", "color:white;background-color:#D4D0C8;border-color:black;border-width:1px;border-style:solid;font-weight:bold;border-collapse:collapse;");

            //this is our header row
            TableRow MainTr = new TableRow();
            MainTr.Style["background-color"] = "#003366";

            // this is the tablecell with the header text
            TableCell MainTd = new TableCell();
            MainTd.ColumnSpan = 2;
            MainTd.HorizontalAlign = HorizontalAlign.Left;
            MainTd.Text = "&nbsp;Colorpick 2004";
            MainTr.Controls.Add(MainTd);

            // this is tablecell with the closebutton
            MainTd = new TableCell();
            MainTd.HorizontalAlign = HorizontalAlign.Right;

            // this is our closebutton
            Button CloseButton = new Button();
            CloseButton.Text = "x";
            CloseButton.Attributes.Add("style", "border-style:Outset;font-weight:bold;width:20px;");
            CloseButton.CausesValidation = false;
            CloseButton.ToolTip = "Close";
            CloseButton.Click += new EventHandler(ShowButton_Click);

            // all add it to our layout table
            MainTd.Controls.Add(CloseButton);
            MainTr.Controls.Add(MainTd);
            MainTable.Controls.Add(MainTr);

            MainTr = new TableRow();

            // lets create our colortables and add them to our maintable
            Table ColorTable;
            TableRow ColorTr = new TableRow();
            TableCell ColorTd = new TableCell();

            for (int i1 = 0; i1 <= 255; i1 += 51)
            {
                MainTd = new TableCell();
                ColorTable = new Table();
                for (int i2 = 0; i2 <= 255; i2 += 51)
                {
                    ColorTr = new TableRow();
                    for (int i3 = 0; i3 <= 255; i3 += 51)
                    {
                        ColorTd = new TableCell();
                        Button ColorButton = new Button();
                        ColorButton.CssClass = "colorbutton";
                        Color c = Color.FromArgb(i1, i2, i3);
                        ColorButton.Style["background-color"] = ColorTranslator.ToHtml(c);
                        ColorButton.ToolTip = ColorButton.Style["background-color"];
                        ColorButton.CausesValidation = false;
                        ColorButton.Click += new EventHandler(ColorButton_Click);
                        ColorTd.Controls.Add(ColorButton);
                        ColorTr.Controls.Add(ColorTd);
                    }
                    ColorTable.Controls.Add(ColorTr);
                }

                MainTd.Controls.Add(ColorTable);
                MainTr.Controls.Add(MainTd);

                if (i1 == 102 || i1 == 255)
                {
                    MainTable.Controls.Add(MainTr);
                    MainTr = new TableRow();
                }
            }

            // add the table to _Label and _Label to control
            _Label.Controls.Add(MainTable);
            Controls.Add(_Label);

            //let us create and add a button to show the colortables
            Button ShowButton = new Button();
            ShowButton.ID = "ShowButton";
            ShowButton.Text = "...";
            ShowButton.Style["width"] = "20px";
            ShowButton.ToolTip = "Show colortables";
            ShowButton.CausesValidation = false;
            ShowButton.Click += new EventHandler(ShowButton_Click);

            Controls.Add(ShowButton);
        }

        //here's three functions for the controls
        private void ShowButton_Click(object sender, EventArgs e)
        {
            ShowColors = !ShowColors;
        }

        private void ColorButton_Click(object sender, EventArgs e)
        {
            this.Text = ((Button)sender).Style["background-color"];
            ShowColors = false;
        }

        private void TextBox_TextChanged(object sender, EventArgs e)
        {
            this.Text = _TextBox.Text;
        }

        //we need lots of javascript which we create on prerender
        protected override void OnPreRender(EventArgs e)
        {
            //if we don't have the javascript in our page yet we'll get it out of cache... and if it's not there... we'll create it
            if (!Page.IsClientScriptBlockRegistered("WMBColorPick"))
            {
                string ClientScript = (string)HttpContext.Current.Cache.Get("WMBColorPick");
                if (ClientScript == null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append("<style type=\"text/css\" media=\"screen\">\n");
                    sb.Append("\tinput.colorbutton {border-style:None;height:10px;width:10px;cursor:pointer;}\n<");
                    sb.Append("/style>\n");
                    sb.Append("\n");
                    sb.Append("<script language=\"JavaScript\" type=\"text/javascript\">\n");
                    sb.Append("\n");
                    sb.Append("function showbutton_click(elmnt){\n");
                    sb.Append("\telmnt=document.getElementById(elmnt);\n");
                    sb.Append("\tif(elmnt.style.visibility=='hidden'){\n");
                    sb.Append("\t\telmnt.style.visibility='visible';\n");
                    sb.Append("\t\t}\n");
                    sb.Append("\telse {\n");
                    sb.Append("\t\telmnt.style.visibility='hidden';\n");
                    sb.Append("\t}\n");
                    sb.Append("}\n");
                    sb.Append("\n");
                    sb.Append("function colorbutton_click(colorbutton, elmnt){\n");
                    sb.Append("\telmnt=document.getElementById(elmnt);\n");
                    sb.Append("\telmnt.style.backgroundColor=colorbutton.style.backgroundColor;\n");
                    sb.Append("\telmnt.value=colorbutton.title;\n");
                    sb.Append("\tvar bright = (parseInt(colorbutton.title.substr(1,2),16)+parseInt(colorbutton.title.substr(3,2),16)+parseInt(colorbutton.title.substr(5,2),16))/3;\n");
                    sb.Append("\tif(bright<=127){\n");
                    sb.Append("\t\telmnt.style.color = 'white';\n");
                    sb.Append("\t\t}\n");
                    sb.Append("\telse {\n");
                    sb.Append("\t\telmnt.style.color = 'black';\n");
                    sb.Append("\t}\n");
                    sb.Append("}\n");
                    sb.Append("\n");
                    sb.Append("function createcolortable(id){\n");
                    sb.Append("var spanid = id + '_ColorSpan';\n");
                    sb.Append("var textboxid = id + '_ColorField';\n");
                    sb.Append("var buttonid = id + '_ShowButton';\n");
                    sb.Append("\n");
                    sb.Append("mytable = document.createElement('TABLE');\n");
                    sb.Append("mytable.style.color='white';\n");
                    sb.Append("mytable.style.backgroundColor='#D4D0C8';\n");
                    sb.Append("mytable.style.borderColor='black';\n");
                    sb.Append("mytable.style.borderWidth='1px';\n");
                    sb.Append("mytable.style.borderStyle='solid';\n");
                    sb.Append("mytable.style.fontWeight='bold';\n");
                    sb.Append("mytable.style.borderCollapse='collapse';\n");
                    sb.Append("\n");
                    sb.Append("mytablebody = document.createElement('TBODY');\n");
                    sb.Append("\n");
                    sb.Append("myrow=document.createElement('TR');\n");
                    sb.Append("myrow.style.backgroundColor='#003366';\n");
                    sb.Append("\n");
                    sb.Append("mycell=document.createElement('TD');\n");
                    sb.Append("\n");
                    sb.Append("mycell.colSpan = '2';\n");
                    sb.Append("mycell.setAttribute('align','left');\n");
                    sb.Append("\n");
                    sb.Append("celltext=document.createTextNode(' ColorPick 2004');\n");
                    sb.Append("mycell.appendChild(celltext);\n");
                    sb.Append("\n");
                    sb.Append("myrow.appendChild(mycell);\n");
                    sb.Append("\n");
                    sb.Append("mycell=document.createElement('TD');\n");
                    sb.Append("mycell.setAttribute('align','right');\n");
                    sb.Append("\n");
                    sb.Append("closebutton=document.createElement('INPUT');\n");
                    sb.Append("closebutton.type='submit';\n");
                    sb.Append("closebutton.value='x';\n");
                    sb.Append("closebutton.style.borderStyle='outset';\n");
                    sb.Append("closebutton.style.fontWeight='bold';\n");
                    sb.Append("closebutton.style.width='20px';\n");
                    sb.Append("closebutton['onclick']=new Function('showbutton_click(\"'+ spanid + '\"); return false');\n");
                    sb.Append("\n");
                    sb.Append("closebutton.setAttribute('title', 'Close');\n");
                    sb.Append("\n");
                    sb.Append("\n");
                    sb.Append("mycell.appendChild(closebutton);\n");
                    sb.Append("\n");
                    sb.Append("myrow.appendChild(mycell);\n");
                    sb.Append("\n");
                    sb.Append("mytablebody.appendChild(myrow);\n");
                    sb.Append("\n");
                    sb.Append("myrow=document.createElement('TR');\n");
                    sb.Append("\n");
                    sb.Append("for(i1=0;i1<6;i1++) {\n");
                    sb.Append("\tmycell=document.createElement('TD');\n");
                    sb.Append("\tmycolortable=document.createElement('TABLE');\n");
                    sb.Append("\tmycolortablebody=document.createElement('TBODY');\n");
                    sb.Append("\t\t\tfor (i2=0; i2<6; i2++ ){\n");
                    sb.Append("\t\t\t\tmycolorrow=document.createElement('TR');\n");
                    sb.Append("\t\t\t\t\tfor (i3=0; i3<6; i3++ ){\n");
                    sb.Append("\t\t\t\t\t\tmycolorcell=document.createElement('TD');\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton=document.createElement('INPUT');\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton.type='submit';\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton.value='';\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton.className = 'colorbutton' ;\n");
                    sb.Append("\t\t\t\t\t\tvar hexcolor = '#' + toHex(i1) + toHex(i2) + toHex(i3);\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton.style.backgroundColor = hexcolor;\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton.setAttribute('title', hexcolor);\n");
                    sb.Append("\t\t\t\t\t\tcolorbutton['onclick']=new Function('colorbutton_click(this,\"' + textboxid + '\"); return false');\n");
                    sb.Append("\t\t\t\t\t\tmycolorcell.appendChild(colorbutton);\n");
                    sb.Append("\t\t\t\t\t\tmycolorrow.appendChild(mycolorcell);\n");
                    sb.Append("\t\t\t\t\t}\n");
                    sb.Append("\t\t\t\tmycolortablebody.appendChild(mycolorrow);\n");
                    sb.Append("\t\t\t}\n");
                    sb.Append("\t\tmycolortable.appendChild(mycolortablebody);\n");
                    sb.Append("\t\tmycell.appendChild(mycolortable);\n");
                    sb.Append("\t\tmyrow.appendChild(mycell); \n");
                    sb.Append("\t\n");
                    sb.Append("\t\tif ( i1 == 2 || i1 == 5 )\n");
                    sb.Append("\t\t{\n");
                    sb.Append("\t\tmytablebody.appendChild(myrow);\n");
                    sb.Append("\t\tmyrow=document.createElement('TR');\n");
                    sb.Append("\t\t}\n");
                    sb.Append("}\n");
                    sb.Append("mytable.appendChild(mytablebody);\n");
                    sb.Append("var myspan = document.getElementById(spanid);\n");
                    sb.Append("myspan.appendChild(mytable);\n");
                    sb.Append("var showbutton = document.getElementById(buttonid);\n");
                    sb.Append("showbutton['onclick']=new Function('showbutton_click(\"'+ spanid + '\"); return false');\n");
                    sb.Append("}\n");
                    sb.Append("\n");
                    sb.Append("function toHex(i){\n");
                    sb.Append("\tswitch(i){\n");
                    sb.Append("\tcase 0: {return '00';}\n");
                    sb.Append("\tcase 1: {return '33';}\n");
                    sb.Append("\tcase 2: {return '66';}\n");
                    sb.Append("\tcase 3: {return '99';}\n");
                    sb.Append("\tcase 4: {return 'CC';}\n");
                    sb.Append("\tcase 5: {return 'FF';}\n");
                    sb.Append("\t}\n");
                    sb.Append("\treturn '00';\n");
                    sb.Append("}\n<");
                    sb.Append("/script>");

                    ClientScript = sb.ToString();
                    HttpContext.Current.Cache.Insert("WMBColorPick", ClientScript);
                }

                Page.RegisterClientScriptBlock("WMBColorPick", ClientScript);
            }

            //create the colortables on pageload if we don't create them serverside
            if (!ShowColors)
            {
                StringBuilder sb2 = new StringBuilder();
                sb2.Append("<script language=\"JavaScript\" type=\"text/javascript\">");
                sb2.Append("createcolortable('" + this.ID + "')<");
                sb2.Append("/script>");
                Page.RegisterStartupScript(this.ID, sb2.ToString());
            }

            base.OnPreRender(e);
        }
    }
}